package api

import (
	"context"
	"encoding/json"
	"fmt"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v5/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/aliyun/credentials-go/credentials"
	credential "github.com/aliyun/credentials-go/credentials"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"math/rand"
	"mxshop_api/user-web/forms"
	"mxshop_api/user-web/global"
	"net/http"
	"strings"
	"time"
)

func GenerateSmsCode(witdh int) string {
	//生成width长度的短信验证码

	numeric := [10]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	r := len(numeric)
	//rand.Seed(time.Now().UnixNano())
	rand.New(rand.NewSource(time.Now().UnixNano()))

	var sb strings.Builder
	for i := 0; i < witdh; i++ {
		_, err := fmt.Fprintf(&sb, "%d", numeric[rand.Intn(r)])
		if err != nil {
			return ""
		}
	}
	return sb.String()
}

func CreateClient() (_result *dysmsapi20170525.Client, _err error) {
	// 工程代码建议使用更安全的无AK方式，凭据配置方式请参见：https://help.aliyun.com/document_detail/378661.html。

	configs := new(credentials.Config).
		SetType("access_key").
		SetAccessKeyId(global.ServerConfig.AliSmsInfo.ApiKey).
		SetAccessKeySecret(global.ServerConfig.AliSmsInfo.Secret)

	akCredential, _err := credential.NewCredential(configs)
	if _err != nil {
		return _result, _err
	}

	config := &openapi.Config{
		Credential: akCredential,
	}
	// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
	config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
	_result = &dysmsapi20170525.Client{}
	_result, _err = dysmsapi20170525.NewClient(config)
	return _result, _err
}

func _main(ctx *gin.Context) (_err error) {
	// 表单验证
	sendSmsForm := forms.SendSmsForm{}
	if err := ctx.ShouldBind(&sendSmsForm); err != nil {
		// 如何返回错误信息
		HandleValidatorError(ctx, err)
		return
	}
	client, _err := CreateClient()

	if _err != nil {
		return _err
	}
	smsCode := GenerateSmsCode(6)
	sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
		PhoneNumbers:  tea.String(sendSmsForm.Mobile),
		SignName:      tea.String("阿里云短信测试"),
		TemplateCode:  tea.String("SMS_154950909"),
		TemplateParam: tea.String("{\"code\":" + smsCode + "}"),
	}
	runtime := &util.RuntimeOptions{}
	tryErr := func() (_e error) {
		defer func() {
			if r := tea.Recover(recover()); r != nil {
				_e = r
			}
		}()
		// 复制代码运行请自行打印 API 的返回值

		response := &dysmsapi20170525.SendSmsResponse{}
		response, _err = client.SendSmsWithOptions(sendSmsRequest, runtime)
		fmt.Printf("返回数据：%#v\n", response)
		if _err != nil {
			return _err
		}

		return nil
	}()

	// 添加到redis中
	//将验证码保存起来 - redis
	rdb := redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", global.ServerConfig.RedisInfo.Host, global.ServerConfig.RedisInfo.Port),
		Password: global.ServerConfig.RedisInfo.Password,
		DB:       global.ServerConfig.RedisInfo.Db,
	})
	rdb.Set(context.Background(), sendSmsForm.Mobile, smsCode, time.Duration(global.ServerConfig.RedisInfo.Expire)*time.Second)

	ctx.JSON(http.StatusOK, gin.H{
		"msg": "发送成功",
	})

	if tryErr != nil {
		var err = &tea.SDKError{}
		if _t, ok := tryErr.(*tea.SDKError); ok {
			err = _t
		} else {
			err.Message = tea.String(tryErr.Error())
		}
		// 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
		// 错误 message
		fmt.Println(tea.StringValue(err.Message))
		// 诊断地址
		var data interface{}
		d := json.NewDecoder(strings.NewReader(tea.StringValue(err.Data)))
		err2 := d.Decode(&data)
		if err2 != nil {
			return err2
		}
		if m, ok := data.(map[string]interface{}); ok {
			recommend, _ := m["Recommend"]
			fmt.Println(recommend)
		}
		_, _err = util.AssertAsString(err.Message)
		if _err != nil {
			return _err
		}
	}
	return _err
}
func SendSMS(ctx *gin.Context) {
	err := _main(ctx)
	if err != nil {
		panic(err)
	}
}
